﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using Genuilder.Extensibility;
using Genuilder.Extensibility.Tests;
using Genuilder.Tests;
using System.IO;
using System.Runtime.Serialization;

namespace Genuilder.Extensions.Tests
{
	public class TestClass
	{
		const string TestProject = "../../Data/TestProject";
		[Fact]
		public void CanCompileExtensions()
		{
			using(var directory = new TestDirectory().Of(TestProject))
			{
				IExtension[] extensions = new IExtension[] 
				{ 
					new AsyncServiceContractsExtension()
					{
					    Files = new string[]{ "Contract1.cs", "Contract2.cs" }
					},
					new ProxyGeneratorExtension()
					{
						Files = new string[] { "Interface1.cs" }
					},
					new StronglyTypedReflectionExtension()
					{
						Files = new string[] { "Class1.cs" }
					}
				};

				var project = Projects.InDirectory(directory.Path).First();
				foreach(var extension in extensions)
				{
					var extensibility = new ExtensibilityFeature();
					extensibility.AddExtensions(extensions);
					project.InstallFeature(extensibility);
					project.Save();
					project.Build().AssertBuild();
				}
			}
		}

		[DataContract]
		public class SpyExtension : IExtension
		{
			
			public SpyExtension(string path)
			{
				Path = path;
			}
			[DataMember]
			public string Path
			{
				get;
				set;
			}
			#region IExtension Members

			public void Execute(ExtensionContext extensionContext)
			{
				StartupProject = extensionContext.ExecutionContext.StartInfo.Project;
				ProjectAssembly = extensionContext.ExecutionContext.ProjectInfo.AssemblyName;
				ProjectNamespace = extensionContext.ExecutionContext.ProjectInfo.RootNamespace;
				ProjectMetadataExtension = extensionContext.GenItems.First().MetadataCollection.Extension;
			}

			#endregion

			public string StartupProject
			{
				get
				{
					return Read("StartupProject");
				}
				set
				{
					Write("StartupProject", value);
				}
			}
			public string ProjectAssembly
			{
				get
				{
					return Read("ProjectAssembly");
				}
				set
				{
					Write("ProjectAssembly", value);
				}
			}
			public string ProjectNamespace
			{
				get
				{
					return Read("ProjectNamespace");
				}
				set
				{
					Write("ProjectNamespace", value);
				}
			}

			public string ProjectMetadataExtension
			{
				get
				{
					return Read("ProjectMetadataExtension");
				}
				set
				{
					Write("ProjectMetadataExtension", value);
				}
			}

			private string Read(string path)
			{
				return File.ReadAllText(System.IO.Path.Combine(Path, path));
			}

			private void Write(string path, string value)
			{
				File.WriteAllText(System.IO.Path.Combine(Path, path), value);
			}

		}

		[Fact]
		public void CanGetProjectPath()
		{
			using(var directory = new TestDirectory().Of(TestProject))
			{
				var project = Projects.InDirectory(directory.Path).First();
				var ex = new ExtensibilityFeature();
				var spy = ex.AddExtension(new SpyExtension(directory.DirectoryInfo.FullName));
				project.InstallFeature(ex);
				project.Save();
				project.Build();
				Assert.Equal(project.Path, spy.StartupProject);
				Assert.Equal("TestProjectNs", spy.ProjectNamespace);
				Assert.Equal("TestProject", spy.ProjectAssembly);
				Assert.Equal(".cs", spy.ProjectMetadataExtension);
			}
		}
	}
}
